////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///  File:        AMCLibrary.h
///  Description: Advanced Modular Cryptographic Library interface.
///  Author:      Chiuta Adrian Marius
///  Created:     22-10-2009
///
///  Licensed under the Apache License, Version 2.0 (the "License");
///  you may not use this file except in compliance with the License.
///  You may obtain a copy of the License at
///  http://www.apache.org/licenses/LICENSE-2.0
///  Unless required by applicable law or agreed to in writing, software
///  distributed under the License is distributed on an "AS IS" BASIS,
///  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
///  See the License for the specific language governing permissions and
///  limitations under the License.
///
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#ifndef __INCLUDED_AMCLIBRARY_H__
#define __INCLUDED_AMCLIBRARY_H__

#include <Windows.h>
#include <tchar.h>

#ifdef _UNICODE
    #define AMCLIB_VERSION 0x00010000
#else
    #define AMCLIB_VERSION 0x80010000
#endif

#ifdef AMCLIBRARY_EXPORTS
    #define AMCLIBRARY_API __declspec(dllexport)
#else
    #define AMCLIBRARY_API __declspec(dllimport)
#endif

#ifndef CALLBACK
    #define CALLBACK __stdcall
#endif

// The types used by AMC lib
typedef unsigned __int8 UINT8;
typedef unsigned __int16 UINT16;
typedef unsigned __int32 UINT32;
typedef unsigned __int64 UINT64;
typedef signed __int8 INT8;
typedef signed __int16 INT16;
typedef signed __int32 INT32;
typedef signed __int64 INT64;
typedef int BOOL;
#define FALSE 0
#define TRUE 1

#define CLASS_ID UINT32
#define ALGORITHM_CLASS_ID 0x00000000

// Returns true of the object is derived from class (RTTI must be enabled)
#define IS_KIND_OF(object, class) (dynamic_cast<class*>(object) != NULL)

/// The interface of every algorithm used by AMC Library
class IAlgorithm
{
public:

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ///
    /// @return         The description of the class.
    ///
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual class IAlgorithmDescription& GetDescription() = 0;

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ///
    /// @return         The ID of the class.
    ///
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual CLASS_ID GetID() = 0;

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ///
    /// @return         The ID of the interface/class from which this class is derived.
    ///
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual CLASS_ID GetInterfaceID() = 0;

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ///
    /// The destructor used to release the resources
    ///
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual ~IAlgorithm() {};
};

/// The interface that must implemented to return information about the AMC Library Algorithm.
class IAlgorithmDescription
{
public:

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ///
    /// @return         The name of the class.
    ///
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual const TCHAR* ClassName() = 0;

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ///
    /// @return         The description of the class.
    ///
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual const TCHAR* ClassDescription() = 0;

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ///
    /// @return         The ID of the interface/class from which this class is derived.
    ///
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual CLASS_ID InterfaceID() = 0;

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ///
    /// @return         The ID of the class. Every class must have one unique ID.
    ///
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual CLASS_ID ClassID() = 0;

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ///
    /// Creates one instance of the class. After the work is done, the returned instance must be deleted.
    ///
    /// @return         Returns the pointer to the new created class.
    ///
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual IAlgorithm* Create() = 0;
};

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///
/// The type of callback used for enumeration of the algorithms
///
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
typedef BOOL (CALLBACK *ACMEnumerationCallback)(IAlgorithmDescription &moduleDescription);

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///
/// The type of function that must be implemented by every module.
///
/// @param acmVersion
///                 The version of the ACM library.
/// @return
///                 The pointer to the description of the library. Also the pointer can be NULL.
///
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
typedef __declspec(dllimport) IAlgorithmDescription* (*GetDescriptionProc)(UINT32 acmVersion);

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///
/// @return The version of the library. The library version is in the form:
///         - HIWORD(version) represent the major version
///         - LOWORD(version) represent the minor version
///
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
AMCLIBRARY_API UINT32 AMCGetVersion();

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///
/// Starts the enumeration of all the supported algorithms.
///
/// @param Callback
///                 The pointer to the function that will be called for every supported algorithm.
///                 The callback will have the parameters set to the class that describe the algorithm.
///                 If the callback returns FALSE, then the enumeration will stop even
///                 if there are more algorithms to enumerate.
///
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
AMCLIBRARY_API void AMCEnumerateAlgorithms(ACMEnumerationCallback Callback);

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///
/// Returns the description for the algorithm identified by the given ID.
///
/// @param classID
///                 The unique ID that identifies the algorithm.
/// @param interfaceID
///                 The unique ID that identifies the interface of the algorithm.
/// @return
///                 The pointer to the algorithm descriptor. If the algorithm is not found, returns NULL.
///
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
AMCLIBRARY_API IAlgorithmDescription* AMCGetAlgorithmDescription(CLASS_ID interfaceID, CLASS_ID classID);

#include "IAlgorithmAES.h"

#endif // __INCLUDED_AMCLIBRARY_H__
